package io.github.bigbird0101.youyishi.spring.bean.load.statistics;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.LoaderClassPath;
import javassist.NotFoundException;

import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

public class BeanLoadStatistics {
    public static final String ORG_SPRINGFRAMEWORK_CONTEXT_SUPPORT_ABSTRACT_APPLICATION_CONTEXT = "org/springframework/context/support/AbstractApplicationContext";

    static {
        System.out.println("Bean测试注入成功可通过 Post http://localhost:8080/test/{className}/{methodName} \r\n " +
                "或者 http://localhost:8080/test/{className}/{methodName}/{methodIndex} 调用bean 通过RequestBody传参");
        System.out.println("bean初始化注入成功 http://localhost:8080/BeanLoadStatistics 可打开监控页面");
    }

    public static void premain(String args, Instrumentation instrumentation){
        instrumentation.addTransformer(new ClassFileTransformer() {
            @Override
            public byte[] transform(ClassLoader loader,
                                    String className,
                                    Class<?> classBeingRedefined,
                                    ProtectionDomain protectionDomain,
                                    byte[] classfileBuffer) {
                if(ORG_SPRINGFRAMEWORK_CONTEXT_SUPPORT_ABSTRACT_APPLICATION_CONTEXT.equals(className)){
                    ClassPool classPool = ClassPool.getDefault();
                    classPool.appendClassPath(new LoaderClassPath(loader));
                    String classReplaceName = ORG_SPRINGFRAMEWORK_CONTEXT_SUPPORT_ABSTRACT_APPLICATION_CONTEXT.replaceAll("/", ".");
                    try {
                        CtClass ctClass = classPool.get(classReplaceName);
                        CtMethod m1 = ctClass.getDeclaredMethod("prepareBeanFactory");
                        m1.insertAfter("io.github.bigbird0101.youyishi.spring.bean.load.statistics.AgentBeanFactoryRegister " +
                                "agentBeanFactoryRegister=new io.github.bigbird0101.youyishi.spring.bean.load.statistics.AgentBeanFactoryRegister()" +
                                ";addBeanFactoryPostProcessor(agentBeanFactoryRegister);" +
                                "beanFactory.registerSingleton(\"agentBeanFactoryRegister\",agentBeanFactoryRegister);");

                        return ctClass.toBytecode();
                    } catch (NotFoundException | CannotCompileException | IOException e) {
                        System.err.println(e);
                        throw new RuntimeException(e);
                    }
                }
                return null;
            }
        });
    }

    public static void agentmain(String agentArgs, Instrumentation inst) {
    }
}
